package com.guodi.map.controller;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.guodi.common.constant.StatusCode;
import com.guodi.common.utils.ReadFileUtil;
import com.guodi.common.utils.UuidUtil;
import com.guodi.core.boot.ctrl.BaseController;
import com.guodi.core.log.logger.GlobalLogger;
import com.guodi.core.tool.api.R;
import com.guodi.map.constant.MapConst;
import com.guodi.map.entity.MapLayer;
import com.guodi.map.entity.MapLayerField;
import com.guodi.map.service.IMapLayerFieldService;
import com.guodi.map.service.IMapLayerService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import net.sf.json.JSONArray;
import net.sf.json.JSONObject;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import springfox.documentation.annotations.ApiIgnore;

import java.util.*;
import java.util.stream.Collectors;


/**
 * @描述：图层字段列表控制类
 * @作者: 代鹏刚
 * @日期: 2019-12-27
 */
@Validated
@RestController
@RequestMapping("/MapLayerField")
@Api(value = "API - MapLayerFieldController", tags = "图层字段列表")
@Slf4j
public class MapLayerFieldController extends BaseController {

    @Autowired
    private IMapLayerFieldService mapLayerFieldService;
    @Autowired
    private IMapLayerService mapLayerService;

    @Autowired
    private GlobalLogger logger;

    /**
     * @描述: 根据实体属性分页查询
     * @入参:
     * @出参:
     * @作者: 代鹏刚
     * @日期: 2019-12-27
     **/
    @PostMapping("/listByEntity")
    @ApiOperation(value = " 根据实体属性分页查询")
    public R listByEntity(Page page, MapLayerField mapLayerField){
        LambdaQueryWrapper<MapLayerField> wrapper = new QueryWrapper().lambda();
        IPage<MapLayerField> iPage = mapLayerFieldService.page(page, wrapper);
        return R.data(iPage);
    }

    /**
     * @描述: 根据主键查询
     * @入参:
     * @出参:
     * @作者: 代鹏刚
     * @日期: 2019-12-27
     **/
    @PostMapping("/findById")
    @ApiOperation(value = "根据主键查询")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "id", value = "ID", required = true,
                    dataType = "string", paramType = "query")
    })
    public R findById(String id) {
        if(StringUtils.isBlank(id)){
            return R.fail(StatusCode.ERROR_CODE_40005,"id不能为空");
        }
        MapLayerField mapLayerField = mapLayerFieldService.getById(id);
        return R.data(mapLayerField);
    }

    /**
     * @描述: 保存字段信息
     * @入参:
     * @出参:
     * @作者: 代鹏刚
     * @日期: 2019-12-27
     **/
    @PostMapping("/save")
    @ApiOperation(value = "保存字段信息")
    public R save(@RequestBody List<MapLayerField> mapLayerFields){
        Set<String> layerIds = new HashSet<>();
        List<MapLayerField> batckAdd = new ArrayList<>();
        int size= mapLayerFields.size();
        for (int i=0;i<size;i++){
            MapLayerField mapLayerField = mapLayerFields.get(i);
            if(mapLayerField==null){
                continue;
            }
            String uuid = UuidUtil.get32UUID();
            mapLayerField.setId(uuid);
            layerIds.add(mapLayerField.getLayerId());
            batckAdd.add(mapLayerField);
        }
        for (String layerId : layerIds) {
            //保存前删除之前的数据
            mapLayerFieldService.deleteByLayerId(layerId);
        }
        mapLayerFieldService.saveBatch(batckAdd);
        return R.data(null);
    }

    /**
     * @描述: 修改
     * @入参:
     * @出参:
     * @作者: 代鹏刚
     * @日期: 2019-12-27
     **/
    @PostMapping("/update")
    @ApiOperation(value = "修改")
    public R update(MapLayerField mapLayerField) {
        prepareData(mapLayerField, false);
        mapLayerFieldService.updateById(mapLayerField);
        return R.data(mapLayerField);
    }

    /**
     * @描述: 根据主键删除
     * @入参: id
     * @出参:
     * @作者: 代鹏刚
     * @日期: 2019-12-27
     **/
    @PostMapping("/delete")
    @ApiOperation(value = "根据主键删除")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "id", value = "ID", required = true,
                    dataType = "string", paramType = "query")
    })
    public R delete(String id){
        mapLayerFieldService.removeById(id);
        return R.data(null);
    }

    /**
     * @描述: 根据图层ID查询字段信息
     * @入参:
     * @出参:
     * @作者: 代鹏刚
     * @日期: 2019/12/27 10:48
     * @备注 20200509 戴伙进修改支持SuperMap类型
     **/
    @PostMapping("/listByLayerId")
    @ApiOperation(value = "根据图层ID查询字段信息")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "layerId", value = "图层ID", required = true, dataType = "string", paramType = "query"),
            @ApiImplicitParam(name = "isSync", value = "是否同步：true/false", dataType = "boolean", paramType = "query")
    })
    public R listByLayerId(@ApiIgnore Page page, String layerId, Boolean isSync) {
        page.setSize(999);
        // 存储图层字段
        List<MapLayerField> fieldList = null;
        // 是否同步(同步根据图层URL查询字段信息)
        if((isSync == null ? false : isSync)){
            // 实例化图层字段集合
            fieldList = new ArrayList<>();
            // 根据id查询图层信息
            MapLayer mapLayer = mapLayerService.getById(layerId);
            //发布的类型
            String releaseType = mapLayer.getReleaseType();
            if("iserver".equals(releaseType)){      //走的是superMap服务的形式
                String layerUrl =mapLayer.getLayerUrl();
                String layerInfoUrl =layerUrl +"/layers.json";
                String jsonStr  = ReadFileUtil.getJsonByUrl(layerInfoUrl).trim();
                JSONArray jsonArray = JSONArray.fromObject(jsonStr);
                JSONObject jsonMap = (JSONObject) jsonArray.get(0);
                JSONObject subLayers = jsonMap.getJSONObject("subLayers");
                JSONArray layers = subLayers.getJSONArray("layers");
                JSONObject datasetInfo = layers.getJSONObject(0).getJSONObject("datasetInfo");
                //获取图层名称
                String layerName = (String) datasetInfo.get("name");
                String dataSourceName = (String) datasetInfo.get("dataSourceName");
                //获取Rest数据服务
                String restDataUrl = layerUrl.substring(0,layerInfoUrl.lastIndexOf("maps"));
                restDataUrl = restDataUrl.replace("map","data");
                restDataUrl +="data/datasources/"+dataSourceName+"/datasets/"+layerName+"/fields.json";
                //再次发送请求
                String jsonDataStr  = ReadFileUtil.getJsonByUrl(restDataUrl).trim();
                JSONObject dataJson = JSONObject.fromObject(jsonDataStr);
                //JSONArray fieldNames = dataJson.getJSONArray("fieldNames");
                JSONArray childUriList = dataJson.getJSONArray("childUriList");
                for (int i = 0; i <childUriList.size() ; i++) {
                    String fieldInfoUrl =childUriList.get(i)+".json";
                    //fieldInfoUrl = URLEncoder.encode(fieldInfoUrl);
                    String layerJsonStr = ReadFileUtil.getJsonByUrl(fieldInfoUrl);
                    JSONObject jsonObject = JSONObject.fromObject(layerJsonStr);
                    JSONObject layerFieldJson = jsonObject.getJSONObject("fieldInfo");
                    String fieldName = layerFieldJson.getString("name");
                    String fieldType = layerFieldJson.getString("type");
                    MapLayerField mapLayerField = new MapLayerField();
                    //设置字段类型
                    if("BOOLEAN".equals(fieldType.toUpperCase())){
                        mapLayerField.setFieldType("boolean");
                    }else if("BYTE".equals(fieldType.toUpperCase()) || "CHAR".equals(fieldType.toUpperCase()) || "TEXT".equals(fieldType.toUpperCase()) || "WTEXT".equals(fieldType.toUpperCase())){
                        mapLayerField.setFieldType("varchar");
                    } else if("DOUBLE".equals(fieldType.toUpperCase()) || "INT16".equals(fieldType.toUpperCase()) || "INT32".equals(fieldType.toUpperCase()) || "INT64".equals(fieldType.toUpperCase()) || "SINGLE".equals(fieldType.toUpperCase())){
                        mapLayerField.setFieldType("number");
                    }else if("LONGBINARY".equals(fieldType.toUpperCase())){
                        mapLayerField.setFieldType("longbinary");
                    }else if(fieldType.toLowerCase().indexOf("DATETIME") != -1){
                        mapLayerField.setFieldType("date");
                    }else{
                        mapLayerField.setFieldType("");
                    }
                    mapLayerField.setId(UuidUtil.get32UUID());
                    mapLayerField.setFieldName(fieldName);
                    mapLayerField.setFieldAlias(layerFieldJson.getString("caption"));
                    mapLayerField.setFieldSize(layerFieldJson.get("maxLength") == null ? "": layerFieldJson.get("maxLength").toString());
                    mapLayerField.setIsShow(1);
                    mapLayerField.setIsLabel(0);
                    mapLayerField.setSort(i+1);
                    mapLayerField.setLayerId(layerId);
                    fieldList.add(mapLayerField);
                }
            }else  if (mapLayer.getReleaseType().equals(MapConst.MAP_SERVICE_TYPE_ARCGIS) || mapLayer.getReleaseType().equals(MapConst.MAP_SERVICE_TYPE_PLATFORM)
                    || mapLayer.getReleaseType().equals(MapConst.MAP_SERVICE_TYPE_BASIS_PLATFORM)) {
                Map<String, String> params = new HashMap();
                params.put("f", "pjson");
                if (mapLayer.getReleaseType().equals(MapConst.MAP_SERVICE_TYPE_PLATFORM) || mapLayer.getReleaseType().equals(MapConst.MAP_SERVICE_TYPE_BASIS_PLATFORM)) {
                    JSONObject authKeyJson = JSONObject.fromObject(mapLayer.getAuthKey());
                    params.put(authKeyJson.getString("key"), authKeyJson.getString("value"));
                }
                // 拼接图层访问url
                String layerUrl = mapLayer.getLayerUrl() + "/" + mapLayer.getLayerTable();
                // 获取图层json
                String layerJsonStr = ReadFileUtil.getStringByUrl(layerUrl, params);
                JSONObject layerJson = JSONObject.fromObject(layerJsonStr);
                if(layerJson.get("fields") != null && !"null".equals(layerJson.get("fields")) && StringUtils.isNotBlank(layerJson.getString("fields"))){
                    // 获取图层几何类型
                    String geometryType = layerJson.get("geometryType") == null ? null : layerJson.get("geometryType").toString();
                    // 获取图层字段集合
                    JSONArray layerArray = layerJson.getJSONArray("fields");
                    for(int i = 0; i < layerArray.size(); i++){
                        JSONObject layerFieldJson = layerArray.getJSONObject(i);
                        String fieldName = layerFieldJson.getString("name");
                        String fieldType = layerFieldJson.getString("type");
                        MapLayerField mapLayerField = new MapLayerField();
                        if(fieldName.toLowerCase().indexOf("objectid") != -1){
                            mapLayerField.setFieldType("number");
                        }else if ("shape".equals(fieldName.toLowerCase())) {
                            mapLayerField.setFieldType(geometryType);
                        }else if(fieldType.toLowerCase().indexOf("integer") != -1 || fieldType.toLowerCase().indexOf("double") != -1){
                            mapLayerField.setFieldType("number");
                        }else if(fieldType.toLowerCase().indexOf("string") != -1 || fieldType.equals("esriFieldTypeOID")){
                            mapLayerField.setFieldType("varchar");
                        }else if(fieldType.toLowerCase().indexOf("date") != -1){
                            mapLayerField.setFieldType("date");
                        }else{
                            mapLayerField.setFieldType("");
                        }
                        mapLayerField.setId(UuidUtil.get32UUID());
                        mapLayerField.setFieldName(fieldName);
                        mapLayerField.setFieldAlias(layerFieldJson.getString("alias"));
                        mapLayerField.setFieldSize(layerFieldJson.get("length") == null ? "": layerFieldJson.get("length").toString());
                        mapLayerField.setIsShow(1);
                        mapLayerField.setIsLabel(0);
                        mapLayerField.setSort(i+1);
                        mapLayerField.setLayerId(layerId);
                        fieldList.add(mapLayerField);
                    }
                }
            }
        }else{
            // 根据图层id查询字段
            fieldList =  mapLayerFieldService.listByLayerId(layerId);
        }
        page.setRecords(fieldList);
        page.setTotal(fieldList.size());
        return R.data(page);
    }

    /**
    * @描述: 根据图层ID查询字段信息
    * @入参:
    * @出参:
    * @作者: 代鹏刚
    * @日期: 2022/4/28 17:14
    **/
    @PostMapping("/listByLayerIds")
    @ApiOperation("根据图层ID查询字段信息")
    public R listByLayerIds(@RequestParam String layerIds,@RequestParam Boolean isSync){
        if(StringUtils.isBlank(layerIds)){
            return R.fail("图层id不能为空");
        }
        Map<String,List<MapLayerField>> result = new HashMap<>();
        List<String> layerList = Arrays.asList(layerIds.split(","));
        List<MapLayer> mapLayers = mapLayerService.listByIds(layerList);
        if(!isSync){
            for (MapLayer layer:mapLayers){
                // 根据图层id查询字段
                List<MapLayerField> mapLayerFields = mapLayerFieldService.listByLayerId(layer.getId());
//                result.put(layer.getLayerTable(),mapLayerFields);
                result = mapLayerFields.stream().collect(Collectors.groupingBy(v -> StringUtils.isEmpty(v.getLayerTable()) ? "" : v.getLayerTable()));
            }
        }else{
            if(mapLayers.size()==1&&"2".equals(mapLayers.get(0).getType())){
//                MapLayer mapLayer = mapLayers.get(0);
//                String layerJsonStr = ReadFileUtil.getStringByUrl(mapLayer.getLayerUrl()+ MapConst.URL_SUFFIX,new HashMap<>());
//                JSONObject jsonObject = JSONObject.fromObject(layerJsonStr);
//                Object geometryType = jsonObject.get("geometryType");
//                List<MapLayerField> layerFields = mapLayerFieldService.getLayerFieldByParseResult(layerJsonStr, mapLayer.getId(), geometryType == null ? "" : geometryType.toString());
//                result.put(mapLayer.getLayerTable(),layerFields);
                //todo 暂时按单个图层处理
                MapLayer mapLayer = mapLayers.get(0);
                result = mapLayerFieldService.parseLayerFieldByParseResult(mapLayer.getLayerUrl(), mapLayer);
            }else{
                for (MapLayer layer:mapLayers){
                    String layerJsonStr = ReadFileUtil.getStringByUrl(layer.getLayerUrl()+"/"+layer.getLayerTable()+ MapConst.URL_SUFFIX,new HashMap<>());
                    JSONObject jsonObject = JSONObject.fromObject(layerJsonStr);
                    Object geometryType = jsonObject.get("geometryType");
                    JSONArray  fieldArray=new JSONArray();
                    Object fields = jsonObject.get("fields");
                    if(fields==null||"null".equals(fields.toString())){
                        Object layers = jsonObject.get("layers");
                        if(layer!=null&&!"null".equals(layers.toString())){
                            JSONArray layerArray = (JSONArray) layers;
                            for (Object layerObj : layerArray) {
                                JSONObject  oneLayer = (JSONObject) layerObj;
                                String layerId = oneLayer.get("id").toString();
                                if(layerId.equals(layer.getLayerTable())){
                                    fields = oneLayer.get("fields");
                                    if(fields!=null&&!"null".equals(fields.toString())){
                                        fieldArray = (JSONArray) fields;
                                        break;
                                    }
                                }
                            }
                        }
                    }else{
                        fieldArray = (JSONArray) fields;
                    }
                    List<MapLayerField> layerFields = mapLayerFieldService.getLayerFieldByParseResult(fieldArray, layer.getId(), geometryType == null ? "" : geometryType.toString());
                    result = layerFields.stream().collect(Collectors.groupingBy(v -> StringUtils.isEmpty(v.getLayerTable()) ? "" : v.getLayerTable()));
                }
            }
        }
        return R.data(result);
    }

    /**
    * @描述: 根据图层地址解析字段
    * @入参:
    * @出参:
    * @作者: 代鹏刚
    * @日期: 2022/4/28 17:14
    **/
    @GetMapping("/parseLayerField")
    @ApiOperation("根据图层地址解析字段")
    public R parseLayerField(String layerUrl,String layerId){
        if(mapLayerService.ogcFlag(layerUrl)){
            return R.data(new HashMap<>());
        }
        MapLayer mapLayer = mapLayerService.getById(layerId);
        Map<String, List<MapLayerField>> stringListMap = mapLayerFieldService.parseLayerFieldByParseResult(layerUrl, mapLayer);
        return R.data(stringListMap);
    }

    /**
    * @描述: 根据服务地址获取所有图层字段
    * @入参:
    * @出参:
    * @作者: 代鹏刚
    * @日期: 2022/4/28 17:14
    **/
    @ApiOperation("根据服务地址获取所有图层字段")
    @GetMapping("/listAllByLayerId")
    public R listAllByLayerId(MapLayer mapLayer) {
        if(StringUtils.isBlank(mapLayer.getId())){
            return R.fail("id不能为空");
        }
        MapLayer layer = mapLayerService.getById(mapLayer.getId());
        if(layer==null){
            return R.data(new ArrayList<>());
        }
        Map<String,List<MapLayerField>> result =new HashMap<>();
//        if("2".equals(layer.getType())) {
//            LambdaQueryWrapper<MapLayer> wrapper = Wrappers.lambdaQuery();
//            wrapper.eq(MapLayer::getParentId, layer.getId());
//            List<MapLayer> list = mapLayerService.list(wrapper);
//            if (list == null || list.isEmpty()) {
//                long start = System.currentTimeMillis();
//                List<MapLayerField> layerFields = mapLayerFieldService.listByLayerId(layer.getId());
//                if (layerFields != null && !layerFields.isEmpty()) {
//                    result.put(layer.getLayerTable(), layerFields);
//                }
//            } else {
//                Map<String,String> idAndName =new HashMap<>();
//                List<String> ids =new ArrayList<>();
//                for (MapLayer layers : list) {
//                    String name = layers.getName();
//                    String layerName = name.split("#")[0];
//                    if(StringUtils.isNotBlank(mapLayer.getLayerName())&&layerName.equals(mapLayer.getLayerName())){
//                        ids.clear();
//                        ids.add(layers.getId());
//                        idAndName.clear();
//                        idAndName.put(layers.getId(),layerName);
//                        break;
//                    }
//                    ids.add(layers.getId());
//                    idAndName.put(layers.getId(),layers.getLayerTable());
//                }
//                long start = System.currentTimeMillis();
//                List<MapLayerField> mapLayerFields = mapLayerFieldService.listByLayerIds(ids);
//                for (MapLayerField mapLayerField : mapLayerFields) {
//                    String layerTable = idAndName.get(mapLayerField.getLayerId());
//                    List<MapLayerField> mapLayerFieldList = result.get(layerTable);
//                    if(mapLayerFieldList==null){
//                        mapLayerFieldList =new ArrayList<>();
//                    }
//                    mapLayerFieldList.add(mapLayerField);
//                    result.put(layerTable,mapLayerFieldList);
//                }
//            }
//        }else if("3".equals(layer.getType())){
//            long start = System.currentTimeMillis();
//            List<MapLayerField> layerFields = mapLayerFieldService.listByLayerId(layer.getId());
//            if (layerFields != null && !layerFields.isEmpty()) {
//                result.put(layer.getLayerTable(), layerFields);
//            }
//        }
        if("2".equals(layer.getType())){
            List<MapLayerField> layerFields = mapLayerFieldService.listByLayerId(layer.getId());
            if (layerFields != null && !layerFields.isEmpty()) {
                result = layerFields.stream().collect(Collectors.groupingBy(v -> StringUtils.isEmpty(v.getLayerTable()) ? "" : v.getLayerTable()));
            }
        }
        return R.data(result);
    }

    /**
     * @描述: 根据专题目录ID获取图层字段信息
     * @入参:
     * @出参:
     * @作者: 代鹏刚
     * @日期: 2020/4/17 15:19
     **/
    @PostMapping("/listByProjectId")
    @ApiOperation(value = "根据专题目录ID获取图层字段信息")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "projectId", value = "专题目录ID", required = true, dataType = "string", paramType = "query")
    })
    public R listByProjectId(String projectId){
        List<MapLayerField> fieldList = mapLayerFieldService.listByProjectId(projectId);
        return R.data(fieldList);
    }

    /**
    * @描述: 图层字段移动排序
    * @入参:
    * @出参:
    * @作者: 代鹏刚
    * @日期: 2021/1/26 17:36
    **/
    @PostMapping("/moveSort")
    @ApiOperation(value = "图层字段移动排序")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "formJson", value = "数组排序json", required = true, dataType = "string", paramType = "query")
    })
    public R moveSort(String formJson){
        List<MapLayerField> mapLayerFields = com.alibaba.fastjson.JSONArray.parseArray(formJson, MapLayerField.class);
        if(mapLayerFields.size() > 0){
            mapLayerFieldService.updateBatchById(mapLayerFields);
        }
        return R.data(null);
    }

    private void prepareData(MapLayerField mapLayerField, boolean isSave) {
        if(isSave){
            mapLayerField.setCreator(getUser().getUserId().toString());
            mapLayerField.setCreateTime(new Date());
            //防止误修改
            mapLayerField.setModifier(null);
            mapLayerField.setModifyTime(null);
        }else{
            mapLayerField.setModifier(getUser().getUserId().toString());
            mapLayerField.setModifyTime(new Date());
            //防止误修改
            mapLayerField.setCreator(null);
            mapLayerField.setCreateTime(null);
        }
    }
}
